package meow

import org.springframework.security.providers.UsernamePasswordAuthenticationToken as AuthToken
import org.springframework.security.context.SecurityContextHolder as SCH
import meow.Account

/**
 * Registration controller.
 */
class RegisterController {

  def authenticateService
  def daoAuthenticationProvider

  static Map allowedMethods = [save: 'POST', update: 'POST']

  /**
   * User Registration Top page.
   */
  def index = {

    // skip if already logged in
    if (authenticateService.isLoggedIn()) {
      redirect action: show
      return
    }

    if (session.id) {
      def account = new Account()
      account.properties = params
      return [account: account]
    }

    redirect uri: '/'
  }

  /**
   * User Information page for current user.
   */
  def show = {

    // get user id from session's domain class.
    def user = authenticateService.userDomain()
    if (user) {
      render view: 'show', model: [account: Account.get(user.id)]
    }
    else {
      redirect action: index
    }
  }

  /**
   * Edit page for current user.
   */
  def edit = {

    def account
    def user = authenticateService.userDomain()
    if (user) {
      account = Account.get(user.id)
    }

    if (!account) {
      flash.message = "[Illegal Access] User not found with id ${params.id}"
      redirect action: index
      return
    }

    [account: account]
  }

  /**
   * update action for current user's edit page
   */
  def update = {

    def account
    def user = authenticateService.userDomain()
    if (user) {
      account = Account.get(user.id)
    }
    else {
      redirect action: index
      return
    }

    if (!account) {
      flash.message = "[Illegal Access] User not found with id ${params.id}"
      redirect action: index, id: params.id
      return
    }

    // if user want to change password. leave passwd field blank, passwd will not change.
    if (params.passwd && params.passwd.length() > 0
        && params.repasswd && params.repasswd.length() > 0) {
      if (params.passwd == params.repasswd) {
        account.passwd = authenticateService.encodePassword(params.passwd)
      }
      else {
        account.passwd = ''
        flash.message = 'The passwords you entered do not match.'
        render view: 'edit', model: [account: account]
        return
      }
    }

    account.userRealName = params.userRealName

    if (account.save()) {
      redirect action: show, id: account.id
    }
    else {
      render view: 'edit', model: [account: account]
    }
  }

  /**
   * Person save action.
   */
  def save = {

    // skip if already logged in
    if (authenticateService.isLoggedIn()) {
      redirect action: show
      return
    }

    def account = new Account()
    account.properties = params

    def config = authenticateService.securityConfig
    def defaultRole = config.security.defaultRole

    def role = Authority.findByAuthority(defaultRole)
    if (!role) {
      account.passwd = ''
      flash.message = 'Default Role not found.'
      render view: 'index', model: [account: account]
      return
    }

    if (params.passwd != params.repasswd) {
      account.passwd = ''
      flash.message = '確認用パスワードがパスワードと一致していません。'
      render view: 'index', model: [account: account]
      return
    }

    account.enabled = true
    account.description = ''
    // 平文のパスワードでいっぺんバリデータをかける
    if (account.save()) {
      role.addToPeople(account)
      // パスワードをハッシュ化して再更新
      account.passwd = authenticateService.encodePassword(params.passwd)
      account.save(flush: true)

      def auth = new AuthToken(account.username, params.passwd)
      def authtoken = daoAuthenticationProvider.authenticate(auth)
      SCH.context.authentication = authtoken
      redirect uri: '/'
    }
    else {
      account.passwd = ''
      render view: 'index', model: [account: account]
    }
  }
}
